package com.whales.lms.rms.scheduler.service;

import java.util.List;

import javax.inject.Inject;

import org.apache.log4j.Logger;
import org.jdom.Document;
import org.jdom.Element;
import org.springframework.stereotype.Service;

import anyframe.common.util.StringUtil;

import com.whales.lms.rms.web.model.PcVO;
import com.whales.lms.rms.web.model.SoftwareVO;
import com.whales.lms.rms.web.service.PcItemService;
import com.whales.lms.rms.web.service.PcService;
import com.whales.lms.rms.web.service.SoftwareService;
import com.whales.lms.rms.web.util.ConstantUtil;
import com.whales.shared.service.BaseService;
import com.whales.shared.util.AgentUtil;
import com.whales.shared.util.NetworkUtil;
import com.whales.shared.util.PjlinkApp;
import com.whales.shared.util.SessionUtil;
import com.whales.shared.util.XmlUtil;

@Service
public class IFService extends BaseService{
	static Logger log = Logger.getLogger(IFService.class);
	@Inject
	private AgentUtil agentUtil;
	@Inject
	private PcService pcService;
	@Inject
	private PcItemService pcItemService;
	@Inject
	private SoftwareService softwareService;
	
	public String agentUpdate(String ip) throws Exception {
		log.trace("Agent update target >> " + ip);
		log.trace("Agent update command >> AGENT");
		String result = this.sendXml(ip, XmlUtil.buildDocForServerCommand("AGENT"));
		log.trace("Agent update result >> " + result);
		return result;
	}
	
	public String agentAlive(String ip) throws Exception{
		log.trace("Agent alive target >> " + ip);
		log.trace("Agent alive command >> ALIVE");
		String result = agentUtil.sendXml(ip, XmlUtil.buildDocForServerCommand("ALIVE"));
		log.trace("Agent alive result >> " + result);
		return result;
	}
	
	public String pcAllOff() throws Exception{
		String rtnResult = ConstantUtil.STATE_OKE;
		for (PcVO pcVO: pcService.getList(new PcVO())) {
			String result = this.pcOff(pcVO.getIp());
			if(!ConstantUtil.STATE_OKE.equals(result)){
				rtnResult = ConstantUtil.STATE_ERR;
			}
		}
		return rtnResult;
	}
	
	public String pcAllOn() throws Exception{
		for (PcVO pcVO: pcService.getList(new PcVO())) {
			this.pcOn(pcVO.getIp(), pcVO.getMacAddress());
		}
		return ConstantUtil.STATE_OKE;
	}
	
	public String pcOff(String ip) throws Exception{
		log.trace("PC Off target >> " + ip);
		log.trace("PC Off command >> PCOFF");
		String result = this.sendXml(ip, XmlUtil.buildDocForServerCommand("PCOFF"));
		log.trace("PC Off result >> " + result);
		//않꺼지는걸 대비해서 한번더 OFF명령을 호출한다.
		if(!ConstantUtil.STATE_ERR.equals(result)){
			result = this.sendXml(ip, XmlUtil.buildDocForServerCommand("PCOFF"));
		}
		//PC의 상태를 PCOFF로 변경한다.
		if(ConstantUtil.STATE_OKE.equals(result)){
			PcVO pcVO = new PcVO();
			pcVO.setIp(ip);
			pcVO.setHwState(ConstantUtil.STATE_OFF);
			pcVO.setSwState(ConstantUtil.STATE_OKE);
			pcService.updateStateByIp(pcVO);
		}
		//projector도 같이 off 한다.
		this.projectorOff(ip);
		return ConstantUtil.STATE_OKE;
	}
	
	public String pcOn(String ip, String macAddress) throws Exception{
		if(StringUtil.isEmpty(macAddress) && macAddress.length() < 10){
			return ConstantUtil.STATE_OKE;
		}
		log.trace("PC On target >> " + ip);
		boolean result = NetworkUtil.wakeOnLan(ip);
		log.trace("PC On result >> " + result);
		this.projectorOn(ip);
		return ConstantUtil.STATE_OKE;
	}
	
	public String pcRestart(String ip) throws Exception{
		log.trace("PC Restart target >> " + ip);
		log.trace("PC Restart command >> PCRE");
		String result = this.sendXml(ip, XmlUtil.buildDocForServerCommand("PCRE"));
		log.trace("PC Restart result >> " + result);
		return result;
	}
	
	public String ping(String ip) {
		log.trace("ping target >> " + ip);
		boolean result = NetworkUtil.ping(ip);
		log.trace("ping result >> " + result);
		if(result){
			return ConstantUtil.STATE_OKE;
		}else{
			return ConstantUtil.STATE_ERR;
		}
	}
	
	public String projectorOff(String ip) throws Exception {
		String projectorIp = pcItemService.findProjectorByPcIp(ip);
		if(StringUtil.isEmpty(projectorIp)){
			return ConstantUtil.STATE_ERR;
		}
		log.trace("Projector Off target >> " + ip);
		PjlinkApp pjlinkApp = new PjlinkApp();
		pjlinkApp.pjlinkSetting(projectorIp, ConstantUtil.PROJECTOR_PORT, "");
		if(pjlinkApp.projectorOff() != null){
			log.trace("Projector Off result >> " + ConstantUtil.STATE_OKE);
			return ConstantUtil.STATE_OKE;
		}else{
			log.trace("Projector Off result >> " + ConstantUtil.STATE_ERR);
			return ConstantUtil.STATE_ERR;
		}
	}
	
	public String projectorOn(String ip) throws Exception {
		String projectorIp = pcItemService.findProjectorByPcIp(ip);
		if(StringUtil.isEmpty(projectorIp)){
			return ConstantUtil.STATE_ERR;
		}
		log.trace("Projector On target >> " + ip);
		PjlinkApp pjlinkApp = new PjlinkApp();
		pjlinkApp.pjlinkSetting(projectorIp, ConstantUtil.PROJECTOR_PORT, "");
		if(pjlinkApp.projectorOn() != null){
			log.trace("Projector On result >> " + ConstantUtil.STATE_OKE);
			return ConstantUtil.STATE_OKE;
		}else{
			log.trace("Projector On result >> " + ConstantUtil.STATE_ERR);
			return ConstantUtil.STATE_ERR;
		}
	}

	private String sendXml(String ip, Document command) throws Exception{
		return agentUtil.sendXml(ip, command);
	}

	public String sendXml(String ip, Document command, String resultElementName) throws Exception{
		return agentUtil.sendXml(ip, command, resultElementName);
	}
	
	public String softwareRestart(String ip) throws Exception{
		log.trace("Software Restart target >> " + ip);
		log.trace("Software Restart command >> SWRE");
		String result = this.sendXml(ip, XmlUtil.buildDocForServerCommand("SWRE"));
		log.trace("Software Restart result >> " + result);
		return result;
	}

	public String softwareVersionUpdate(String ip) throws Exception{
		log.trace("Software version update target >> " + ip);
		Document doc = new Document();
		Element root = new Element("sever-command");
		doc.setRootElement(root);
		Element command = new Element("command");
		command.setText("SWUP");
		root.addContent(command);
		try {
			List<SoftwareVO> list = softwareService.getVersionListByIp(ip);
			for (SoftwareVO vo : list) {
				Element swlist = new Element("swlist");
				swlist.addContent(softwareService.addSoftwareElement("name",vo.getFileName())); //.replace(".zip", ".exe")
				swlist.addContent(softwareService.addSoftwareElement("svrpath",SessionUtil.getAttribute("SERVER_FULL_PATH")+"/software/downloadSoftware.do?id="+vo.getId()));
				swlist.addContent(softwareService.addSoftwareElement("version",vo.getFileVer()));
				root.addContent(swlist);		
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		log.trace("Software version update command >> SWUP");
		String result = this.sendXml(ip, doc);
		log.trace("Software version update result >> " + result);
		return result;
	}
}